﻿using PLCS.Application.Contracts.ErrorLogApp;
using PLCS.Application.Contracts.ErrorLogApp.Dtos;
using PLCS.Domain.Logs;

using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;

namespace PLCS.Application.ErrorLogApp;

public class ErrorLogAppService : CrudAppService<ErrorLog, ErrorLogDto, Guid, PagedResultRequestDto, ErrorLogEditDto>, IErrorLogAppService
{
    private readonly ErrorLogManager _errorLogManager;

    public ErrorLogAppService(IRepository<ErrorLog, Guid> repository, ErrorLogManager errorLogManager) : base(repository)
    {
        _errorLogManager = errorLogManager;
    }

    public async Task DiseposeErrorAsync(Guid Id, string reason, string solution)
    {
        await _errorLogManager.DisposeErrorLogAsync(Id, reason, solution);
    }

    public async Task DiseposeAllErrorAsync()
    {
        await _errorLogManager.DiseposeAllErrorAsync();
    }

    public async Task<List<ErrorLogDto>> GetUnDisposedErrorAsync()
    {
        var query = await ReadOnlyRepository.GetQueryableAsync();
        query = query.Where(x => x.IsDisposed == YesNo.否);
        var entities = await AsyncExecuter.ToListAsync(query);
        return await MapToGetListOutputDtosAsync(entities);
    }

    public async Task<PagedResultDto<ErrorLogDto>> GetListBySearchAsync(PagedResultRequestDto input, string? code, string? kind, string? source, string? startTime, string? endTime)
    {
        await CheckGetListPolicyAsync();

        var query = await CreateFilteredQueryAsync(input);
        bool isStartTime = DateTime.TryParse(startTime, out DateTime StartDateTime);
        query = query.WhereIf(isStartTime, x => x.CreationTime > StartDateTime);
        bool isEndTime = DateTime.TryParse(endTime, out DateTime EndDateTime);
        query = query.WhereIf(isEndTime, x => x.CreationTime < EndDateTime);
        query = query.WhereIf(!string.IsNullOrEmpty(code), x => x.Code == code)
            .WhereIf(!string.IsNullOrEmpty(kind), x => x.Kind == kind)
            .WhereIf(!string.IsNullOrEmpty(source), x => x.Source == source)
            .OrderBy(x => x.IsDisposed);
        var totalCount = await AsyncExecuter.CountAsync(query);

        query = ApplyPaging(query, input);

        var entities = await AsyncExecuter.ToListAsync(query);
        var entityDtos = await MapToGetListOutputDtosAsync(entities);

        return new PagedResultDto<ErrorLogDto>(
            totalCount,
            entityDtos
        );
    }
}